package com.zhentao.payment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhentao.payment.entity.PaymentOrder;
import com.zhentao.payment.mapper.PaymentOrderMapper;
import com.zhentao.payment.service.PaymentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 支付服务实现类
 */
@Service
public class PaymentServiceImpl extends ServiceImpl<PaymentOrderMapper, PaymentOrder> implements PaymentService {

    /**
     * 创建支付订单
     * 1. 生成唯一的订单编号
     * 2. 设置订单初始状态为待支付
     * 3. 保存订单信息到数据库
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PaymentOrder createPaymentOrder(Long userId, Long driverId, BigDecimal amount, Integer paymentType) {
        PaymentOrder order = new PaymentOrder();
        order.setOrderNo(generateOrderNo());
        order.setUserId(userId);
        order.setDriverId(driverId);
        order.setAmount(amount);
        order.setStatus(0); // 待支付
        save(order);
        return order;
    }

    /**
     * 处理支付回调
     * 1. 查询订单信息
     * 2. 验证订单状态是否为待支付
     * 3. 更新订单状态为支付成功
     * 4. 后续可以通过消息队列通知其他服务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlePaymentCallback(String orderNo, String tradeNo, Integer paymentType) {
        PaymentOrder order = queryPaymentOrder(orderNo);
        if (order != null && order.getStatus() == 0) {
            order.setStatus(1); // 支付成功
            updateById(order);
            // TODO: 发送支付成功事件，通知其他服务
        }
    }

    /**
     * 查询支付订单
     * 通过订单编号查询订单详细信息
     */
    @Override
    public PaymentOrder queryPaymentOrder(String orderNo) {
        return lambdaQuery().eq(PaymentOrder::getOrderNo, orderNo).one();
    }

    /**
     * 取消支付订单
     * 1. 查询订单信息
     * 2. 验证订单状态是否为待支付
     * 3. 更新订单状态为支付失败
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelPaymentOrder(String orderNo) {
        PaymentOrder order = queryPaymentOrder(orderNo);
        if (order != null && order.getStatus() == 0) {
            order.setStatus(2); // 支付失败
            updateById(order);
        }
    }

    /**
     * 生成订单编号
     * 使用UUID生成唯一的订单编号，并添加PAY前缀
     *
     * @return 生成的订单编号
     */
    private String generateOrderNo() {
        return "PAY" + UUID.randomUUID().toString().replace("-", "").substring(0, 28);
    }

    @Override
    public IPage<PaymentOrder> queryPaymentList(String orderNo, Integer status, Integer paymentType, Integer page, Integer size) {
        LambdaQueryWrapper<PaymentOrder> wrapper = new LambdaQueryWrapper<>();

        // 添加查询条件
        if (StringUtils.hasText(orderNo)) {
            wrapper.like(PaymentOrder::getOrderNo, orderNo);
        }
        if (status != null) {
            wrapper.eq(PaymentOrder::getStatus, status);
        }

        // 按创建时间降序排序
        wrapper.orderByDesc(PaymentOrder::getCreateTime);

        // 执行分页查询
        return page(new Page<>(page, size), wrapper);
    }

    @Override
    public Map<String, Object> generateAlipayQrCode(String orderNo, BigDecimal amount) {
        // TODO: 调用支付宝SDK生成二维码
        Map<String, Object> result = new HashMap<>();
        result.put("qrCodeBase64", "base64编码的二维码图片");
        result.put("expireTime", LocalDateTime.now().plusMinutes(30));
        return result;
    }

    @Override
    public String queryPaymentStatus(String orderNo) {
        PaymentOrder order = queryPaymentOrder(orderNo);
        if (order == null) {
            return "NOT_FOUND";
        }

        // 检查订单是否过期（30分钟）
        if (order.getCreateTime().plusMinutes(30).isBefore(LocalDateTime.now())) {
            return "EXPIRED";
        }

        switch (order.getStatus()) {
            case 1:
                return "PAID";
            case 2:
                return "CANCELLED";
            default:
                return "UNPAID";
        }
    }

}
